package com.youxin.foundation.db.redis;

import java.text.ParseException;
import java.util.List;
import java.util.Map;


import com.youxin.foundation.utils.JsonUtils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPubSub;

/**
 * Redis集群对象
 * @author yingde.cao
 *
 */
public class RedisClusterCommand {
	public static final String OK="OK";
	private static Object lockObj=new Object();
	private  JedisCluster redisCluster=null;
	
	private static RedisClusterCommand instance=null;
	private RedisClusterBean redisClusterBean;

	public RedisClusterCommand(RedisClusterBean redisClusterBean) throws ParseException
	{
		this.redisClusterBean=redisClusterBean;
		this.redisCluster=redisClusterBean.getRedis();
	}
	
	public static void initConfig(RedisClusterBean redisClusterBean) throws ParseException
	{
		if(instance!=null){
			return;
		}
		synchronized (lockObj) {
			if(instance==null){
				instance=new RedisClusterCommand(redisClusterBean);
			}
		}
	}
	
	public static boolean isRedisOk(String result)
	{
		return RedisClusterCommand.OK.equalsIgnoreCase(result);

	}
	
	public static RedisClusterCommand instance()
	{
		return instance;
	}
	
	public RedisClusterBean getRedisClusterBean() {
		return redisClusterBean;
	}

	public void setRedisClusterBean(RedisClusterBean redisClusterBean) {
		this.redisClusterBean = redisClusterBean;
	}

	public JedisCluster getRedisCluster(){
		return redisCluster;
	}
	
	private static JedisCluster getRedis() {
		return instance.getRedisCluster();
	}

	/**
	 * 执行多条命令接口
	 * @param commandable 函数式接口
	 */
	public void execCommand(MultiCommandable<JedisCluster> commandable)
	{
		JedisCluster redisCluster=getRedis();
		commandable.execute(redisCluster);
	}
	/**
	 * redis集群锁机制
	 * @param key
	 * @param timeoutMillis
	 * @param commandable
	 */
	public void lockCommand(String key,long timeoutMillis,JedisCommandsable<JedisCluster> commandable)
	{
		JedisCluster redisCluster=getRedis();
		RedisDistributedLock<JedisCluster>  redisDistributedLock=new RedisDistributedLock<JedisCluster>(redisCluster);
		redisDistributedLock.lock(key, timeoutMillis, commandable);
	}
	
	/**
	 * 设置redis的key和值
	 * @param key
	 * @param value
	 * @return
	 */
	public static String set(String key,String value) {
		return getRedis().set(key, value);
	}
	/**
	 * 
	 * @Title: setnx 
	 * @Description: 只有不存在的时候才设置
	 * @param @param key key名称
	 * @param @param value  key值 
	 * @param @return
	 * @return Long
	 * @throws
	 */
	public static Long setnx(String key, String value) {
    	return getRedis().setnx(key, value);
    }
	/**
	 * 
	 * @Title: getSet 
	 * @Description: 将给定 key 的值设为 value ，并返回 key 的旧值(old value)
	 * 返回给定 key 的旧值。当 key 没有旧值时，也即是， key 不存在时，返回 nil
	 * @param @param key
	 * @param @param value
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String getSet(String key, String value) {
        return getRedis().getSet(key, value);
    }
	
	/**
	 * 设置key并加上过期时间
	 * @param key key名称
	 * @param value  key值 
	 * @param seconds  过期时间
	 * @return
	 */
	public static String set(String key,String value,int seconds) {
		return getRedis().setex(key,seconds,value);
	}
	
	/**
	 * 设置key过期的时间,这个方法是确定key值存在的情况下
	 * @param key key名称
	 * @param seconds 过期时间
	 * @return
	 */
	public static Long set(String key,int seconds) {
		return getRedis().expire(key,seconds);
	}
	
    public static String hmset(final String key, final Map<String, String> hash) {
		return getRedis().hmset(key,hash);
	}
    
    public static Map<String, String> hgetAll(final String key) 
    {
    	return getRedis().hgetAll(key);
    }
    
    public static List<String> hgetFields(final String key,final String... fields) 
    {
    	return getRedis().hmget(key, fields);
    }
    
    public static String hget(final String key, final String field)
    {
    	return getRedis().hget(key, field);
    }
    
    public static List<String> hmget(final String key, final String... fields)
    {
    	return getRedis().hmget(key, fields);
    }
    
    public static Long hset(final String key, final String field, final String value) {
    	return getRedis().hset(key, field, value);
    }
    
	
	public static String setObject(String key, Object obj) {
		return getRedis().set(key, JsonUtils.objectToFasterxmlJsonString(obj));
	}
	
	
	
	
	public static long delete(String key) {
		return getRedis().del(key);
	}
	
	public static String get(String key){
		return getRedis().get(key);
	}
	
	public static <T> T getObject(String key, Class<T> clazz){
		String jsonString=getRedis().get(key);
		return JsonUtils.stringToFasterxmlObject(jsonString, clazz);
	}
	
	/**
	 * @param key
	 * @param seconds 秒
	 */
	public static void express(String key, int seconds){
		getRedis().expire(key, seconds);
	}
	
	public static boolean exists(String key){
		
		return getRedis().exists(key);
	}
	
	public static void subscrible(final JedisPubSub jedisPubSub,String... channels)
	{		
		getRedis().subscribe(jedisPubSub, channels);
	}
	
}
